using System;
using System.Data;

namespace SharpObjects.Data
{

    public class DbReaderRow
    {
        protected IDataReader dataReader;

        public DbReaderRow(IDataReader dataReader)
        {
            this.dataReader = dataReader;
            this.strprop = new StringProperty(this);
            this.intprop = new IntegerProperty(this);
            this.longprop = new LongProperty(this);
            this.dblprop = new DoubleProperty(this);
            this.dtprop = new DateTimeProperty(this);
            this.boolprop = new BooleanProperty(this);
        }

        public IDataReader Row { get { return dataReader; } }

        public bool GetBoolean(string columnName)
        {
            if(dataReader[columnName] == null || dataReader[columnName] == DBNull.Value)
            {
                throw new Exception(string.Format("The value of the column \"{0}\" is NULL", columnName));
            }
            string stringValue = dataReader[columnName].ToString().Trim();

            if (stringValue == "0")
            {
                return false;
            }
            else if (stringValue == "1")
            {
                return true;
            }
            else if (stringValue.ToUpper() == "Y")
            {
                return true;
            }
            else if (stringValue.ToUpper() == "N")
            {
                return false;
            }
            else if (stringValue.ToUpper() == "T")
            {
                return true;
            }
            else if (stringValue.ToUpper() == "F")
            {
                return false;
            }
            else
            {
                return Convert.ToBoolean(stringValue);
            }
        }

        public bool GetBoolean(string columnName, bool defaultValue)
        {
            if(dataReader[columnName] == null || dataReader[columnName] == DBNull.Value)
            {
                return defaultValue;
            }
            return this.GetBoolean(columnName);
        }

        protected BooleanProperty boolprop;
        public BooleanProperty BooleanValue { get { return this.boolprop; } }

        public DateTime GetDateTime(string columnName)
        {
            if(dataReader[columnName] == null || dataReader[columnName] == DBNull.Value)
            {
                throw new Exception(string.Format("The value of the column \"{0}\" is NULL", columnName));
            }
            return (DateTime)dataReader[columnName];
        }

        public DateTime GetDateTime(string columnName, DateTime defaultValue)
        {
            if(dataReader[columnName] == null || dataReader[columnName] == DBNull.Value)
            {
                return defaultValue;
            }
            return this.GetDateTime(columnName);
        }

        protected DateTimeProperty dtprop;
        public DateTimeProperty DateTimeValue { get { return this.dtprop; } }

        public double GetDouble(string columnName)
        {
            if(dataReader[columnName] == null || dataReader[columnName] == DBNull.Value)
            {
                throw new Exception(string.Format("The value of the column \"{0}\" is NULL", columnName));
            }
            string stringValue = dataReader[columnName].ToString().Trim();
            return Convert.ToDouble(stringValue);
        }

        public double GetDouble(string columnName, double defaultValue)
        {
            if(dataReader[columnName] == null || dataReader[columnName] == DBNull.Value)
            {
                return defaultValue;
            }
            return this.GetDouble(columnName);
        }

        protected DoubleProperty dblprop;
        public DoubleProperty DoubleValue { get { return this.dblprop; } }

        public decimal GetDecimal(string columnName)
        {
            if(dataReader[columnName] == null || dataReader[columnName] == DBNull.Value)
            {
                throw new Exception(string.Format("The value of the column \"{0}\" is NULL", columnName));
            }
            string stringValue = dataReader[columnName].ToString().Trim();
            return Convert.ToDecimal(stringValue);
        }

        public decimal GetDecimal(string columnName, decimal defaultValue)
        {
            if(dataReader[columnName] == null || dataReader[columnName] == DBNull.Value)
            {
                return defaultValue;
            }
            return this.GetDecimal(columnName);
        }

        protected DecimalProperty decprop;
        public DecimalProperty DecimalValue { get { return this.decprop; } }

        public int GetInteger(string columnName)
        {
            if(dataReader[columnName] == null || dataReader[columnName] == DBNull.Value)
            {
                throw new Exception(string.Format("The value of the column \"{0}\" is NULL", columnName));
            }
            string stringValue = dataReader[columnName].ToString().Trim();
            return Convert.ToInt32(stringValue);
        }

        public int GetInteger(string columnName, int defaultValue)
        {
            if(dataReader[columnName] == null || dataReader[columnName] == DBNull.Value)
            {
                return defaultValue;
            }
            return this.GetInteger(columnName);
        }

        protected IntegerProperty intprop;
        public IntegerProperty IntegerValue { get { return this.intprop; } }

        public long GetLong(string columnName)
        {
            if(dataReader[columnName] == null || dataReader[columnName] == DBNull.Value)
            {
                throw new Exception(string.Format("The value of the column \"{0}\" is NULL", columnName));
            }
            string stringValue = dataReader[columnName].ToString().Trim();
            return Convert.ToInt64(stringValue);
        }

        public long GetLong(string columnName, long defaultValue)
        {
            if(dataReader[columnName] == null || dataReader[columnName] == DBNull.Value)
            {
                return defaultValue;
            }
            return this.GetLong(columnName);
        }

        protected LongProperty longprop;
        public LongProperty LongValue { get { return this.longprop; } }

        public string GetString(string columnName)
        {
            if(dataReader[columnName] == null || dataReader[columnName] == DBNull.Value)
            {
                throw new Exception(string.Format("The value of the column \"{0}\" is NULL", columnName));
            }
            return dataReader[columnName].ToString();
        }

        public string GetString(string columnName, string defaultValue)
        {
            if(dataReader[columnName] == null || dataReader[columnName] == DBNull.Value)
            {
                return defaultValue;
            }
            return this.GetString(columnName);
        }

        protected StringProperty strprop;
        public StringProperty StringValue { get { return this.strprop; } }

        public class StringProperty
        {
            protected DbReaderRow row;
            public StringProperty(DbReaderRow row) { this.row = row; }

            public string this[string columnName] { get { return this.row.GetString(columnName); } }
            public string this[string columnName, string defaultValue] { get { return this.row.GetString(columnName, defaultValue); } }
        }

        public class IntegerProperty
        {
            protected DbReaderRow row;
            public IntegerProperty(DbReaderRow row) { this.row = row; }

            public int this[string columnName] { get { return this.row.GetInteger(columnName); } }
            public int this[string columnName, int defaultValue] { get { return this.row.GetInteger(columnName, defaultValue); } }
        }

        public class LongProperty
        {
            protected DbReaderRow row;
            public LongProperty(DbReaderRow row) { this.row = row; }

            public long this[string columnName] { get { return this.row.GetLong(columnName); } }
            public long this[string columnName, long defaultValue] { get { return this.row.GetLong(columnName, defaultValue); } }
        }

        public class DoubleProperty
        {
            protected DbReaderRow row;
            public DoubleProperty(DbReaderRow row) { this.row = row; }

            public double this[string columnName] { get { return this.row.GetDouble(columnName); } }
            public double this[string columnName, double defaultValue] { get { return this.row.GetDouble(columnName, defaultValue); } }
        }

        public class DecimalProperty
        {
            protected DbReaderRow row;
            public DecimalProperty(DbReaderRow row) { this.row = row; }

            public decimal this[string columnName] { get { return this.row.GetDecimal(columnName); } }
            public decimal this[string columnName, decimal defaultValue] { get { return this.row.GetDecimal(columnName, defaultValue); } }
        }

        public class DateTimeProperty
        {
            protected DbReaderRow row;
            public DateTimeProperty(DbReaderRow row) { this.row = row; }

            public DateTime this[string columnName] { get { return this.row.GetDateTime(columnName); } }
            public DateTime this[string columnName, DateTime defaultValue] { get { return this.row.GetDateTime(columnName, defaultValue); } }
        }

        public class BooleanProperty
        {
            protected DbReaderRow row;
            public BooleanProperty(DbReaderRow row) { this.row = row; }

            public bool this[string columnName] { get { return this.row.GetBoolean(columnName); } }
            public bool this[string columnName, bool defaultValue] { get { return this.row.GetBoolean(columnName, defaultValue); } }
        }

    }




}
